module Installr::Client::Command
  class Group < Base
    def create(group_name, group_description)
      puts "[group:create] create group #{group_name} #{group_description}" if @options[:verbose]
      @log.info("[group:create] create group #{group_name} #{group_description}")

      if @storage.create_group(group_name, group_description) != 0
        puts "[group:create] cannot create group #{group_name}. Check the list of group."
        @log.error("[group:create] cannot create group #{group_name}. Check the list of groups.")
        return -1
      end
      return 0
    end

    def delete(group_name)
      puts "[group:delete] delete group #{group_name}" if @options[:verbose]
      @log.info("[group:delete] delete group #{group_name}")

      if @storage.delete_group(group_name) != 0
        puts "[group:delete] cannot delete group #{group_name}. Check the list of group."
        @log.error("[group:delete] cannot delete group #{group_name}. Check the list of groups.")
        return -1
      end
      return 0
    end

    def info(group_name)
      puts "[group:info] info group #{group_name}" if @options[:verbose]
      @log.info("[group:info] info group #{group_name}")

      group = @storage.info_group(group_name)
      if group
        puts "[group:info] information of the group #{group_name}: "
        group.each { |field| print "#{field}" }
        puts " ---"
        return 0
      else
        puts "[group:info] cannot find group #{group_name}"
        @log.error("[group:info] cannot find group #{group_name}")
        return -1
      end
    end

    def list
      puts "[group:list] list groups" if @options[:verbose]
      @log.info("[group:list] list groups")

      groups = @storage.list_groups
      if groups
        puts "[group:list] current group listings: "
        groups.each { |group| print "#{group} " }
        puts " ---"
      else
        puts "[group:list] cannot find group listings"
        @log.error("[group:list] cannot find group listings")
        return -1
      end
      return 0
    end

    def log(group_name)
      puts "[group:log] show log from group #{group_name}" if @options[:verbose]
      @log.info("[group:log] show log from group #{group_name}")

      agents = @storage.list_agents(group_name)
      if agents
        group_result = 0
        agents.each do
          |agent_name|
          agent_result = Installr::Client::Command.const_get(:agent.to_s.capitalize).new(@storage, @log, @options).send(:log, agent_name)
          # try again
          if agent_result == -2
            puts "[group:log] #{agent_name}: retrying once again"
            @log.error("[group:log] #{agent_name}: retrying once again")
            agent_result = Installr::Client::Command.const_get(:agent.to_s.capitalize).new(@storage, @log, @options).send(:log, agent_name)
          end
          group_result = -1 if agent_result < 0
        end
        return group_result
      else
        puts "[group:log] cannot find group #{group_name}"
        @log.error("[group:log] cannot find group #{group_name}")
        return -1
      end
    end

    def show_status(group_name)
      puts "[group:show_status] show status from group #{group_name}" if @options[:verbose]
      @log.info("[group:show_status] show status from group #{group_name}")

      agents = @storage.list_agents(group_name)
      if agents
        group_result = 0
        agents.each do
          |agent_name|
          agent_result = Installr::Client::Command.const_get(:agent.to_s.capitalize).new(@storage, @log, @options).send(:show_status, agent_name)
          # try again
          if agent_result == -2
            puts "[group:show_status] #{agent_name}: retrying once again"
            @log.error("[group:show_status] #{agent_name}: retrying once again")
            agent_result = Installr::Client::Command.const_get(:agent.to_s.capitalize).new(@storage, @log, @options).send(:show_status, agent_name)
          end
          group_result = -1 if agent_result < 0
        end
        return group_result
      else
        puts "[group:show_status] cannot find group #{group_name}"
        @log.error("[group:show_status] cannot find group #{group_name}")
        return -1
      end
    end

    def execute_bootstrap(group_name)
      puts "[group:execute_bootstrap] execute bootstrap group #{group_name}" if @options[:verbose]
      @log.info("[group:execute_bootstrap] execute bootstrap group #{group_name}")

      agents = @storage.list_agents(group_name)

      if agents
        arr = []
        i = 0
        puts "-- bootstrap result -----"
        agents.each do |agent_name|
          arr[i] = Thread.new {
            Thread.current["agent"] = agent_name
            Thread.current["result"] = Installr::Client::Command.const_get(:agent.to_s.capitalize).new(@storage, @log, @options).send(:execute_bootstrap, agent_name)
          }
          i = i + 1
        end
        group_result = 0
        arr.each { |t| t.join }
        arr.each do
          |t|
          if t["result"] == -2
            puts "[group:execute_bootstrap] rebootstraping agent #{t["agent"]} ..."
            @log.info("[group:execute_bootstrap] rebootstraping agent #{t["agent"]} ...")
            agent_again_result = Installr::Client::Command.const_get(:agent.to_s.capitalize).new(@storage, @log, @options).send(:execute_bootstrap, t["agent"])
            group_result = -1 if agent_again_result < 0
          end
        end
        puts "---------------------"
        return group_result
      else
        puts "[group:execute_bootstrap] cannot find group #{group_name}"
        @log.error("[group:execute_bootstrap] cannot find group #{group_name}")
        return -1
      end
    end
  end
end
